bitkeeper revision 1.580.1.1 (3fafd2c85ofrHsrmRaYOxYp49iwWOA)
authorsmh22@labyrinth.cl.cam.ac.uk <smh22@labyrinth.cl.cam.ac.uk>
Mon, 10 Nov 2003 18:02:48 +0000 (18:02 +0000)
committersmh22@labyrinth.cl.cam.ac.uk <smh22@labyrinth.cl.cam.ac.uk>
Mon, 10 Nov 2003 18:02:48 +0000 (18:02 +0000)
new vbd probe world

12 files changed:
BitKeeper/etc/ignore
tools/internal/Makefile
tools/internal/xi_phys_grant.c
xen/drivers/block/xen_block.c
xen/drivers/block/xen_vbd.c
xen/drivers/ide/ide-xeno.c
xen/drivers/scsi/sd.c
xen/include/hypervisor-ifs/block.h
xen/include/hypervisor-ifs/vbd.h
xen/include/xeno/vbd.h
xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_block.c
xenolinux-2.4.22-sparse/arch/xeno/drivers/dom0/dom0_core.c

index 2ca7761ef49e78e3a41cb8ab0a2fdbf10f2aaad2..171cca7f9b8378d065136f260f10b00049b4a31b 100644 (file)
@@ -483,3 +483,8 @@ xen/common/debug.c~
 xen/common/debug.o
 tools/internal/xi_restore_linux
 tools/internal/xi_save_linux
+tools/internal/xi_vbd_add
+tools/internal/xi_vbd_create
+tools/internal/xi_vbd_info
+tools/internal/xi_vbd_list
+xen/drivers/scsi/BusLogic.o
index 03a36dc27722952ccf5c1def6bff569405317639..3979cace5b6c2cf2383259be4c849dfaf93c1834 100644 (file)
@@ -10,6 +10,7 @@ OBJS     = $(patsubst %.c,%.o,$(SRCS))
 TARGETS  = xi_create xi_start xi_stop xi_destroy xi_build 
 TARGETS += xi_phys_grant xi_list xi_save_linux xi_restore_linux
 TARGETS += xi_sched_global xi_sched_domain xi_usage xi_vif_params
+TARGETS += xi_vbd_create xi_vbd_add xi_vbd_list xi_vbd_info 
 INSTALL  = $(TARGETS) xi_vifinit xi_helper
 
 all: check-for-zlib $(TARGETS)
index c5a608ce6171468317b00aa7b3f3a82b53438266..9f24ff56b0181d0027c5731ea672ea261bc39d08 100644 (file)
@@ -30,13 +30,13 @@ int main(int argc, char *argv[])
     vdevice = device + atoi(argv[6]);
     
     op.cmd = BLOCK_IO_OP_VBD_CREATE; 
-    op.u.create_info.domain  = domain; 
-    op.u.create_info.vdevice = vdevice; 
-    op.u.create_info.mode    = 0; 
+    op.u.create_params.domain  = domain; 
+    op.u.create_params.vdevice = vdevice; 
+    op.u.create_params.mode    = 0; 
     if ( strchr(argv[1], 'r') )
-       op.u.create_info.mode |= VBD_MODE_R;
+       op.u.create_params.mode |= VBD_MODE_R;
     if ( strchr(argv[1], 'w') )
-        op.u.create_info.mode |= VBD_MODE_W;
+        op.u.create_params.mode |= VBD_MODE_W;
 
     ret = do_block_io_op(&op);
 
@@ -48,12 +48,12 @@ int main(int argc, char *argv[])
 
 
     op.cmd = BLOCK_IO_OP_VBD_ADD; 
-    op.u.add_info.domain  = domain; 
-    op.u.add_info.vdevice = vdevice;
+    op.u.add_params.domain  = domain; 
+    op.u.add_params.vdevice = vdevice;
 
-    op.u.add_info.extent.device       = device; 
-    op.u.add_info.extent.start_sector = atol(argv[4]);
-    op.u.add_info.extent.nr_sectors   = atol(argv[5]);
+    op.u.add_params.extent.device       = device; 
+    op.u.add_params.extent.start_sector = atol(argv[4]);
+    op.u.add_params.extent.nr_sectors   = atol(argv[5]);
 
     ret = do_block_io_op(&op);
 
index 034c5edc7535c236459a5a334e654cd056b901e3..d1572122711058f356f493c7a503fe3cf4be847d 100644 (file)
@@ -73,7 +73,6 @@ static void unlock_buffer(struct task_struct *p,
 static void io_schedule(unsigned long unused);
 static int do_block_io_op_domain(struct task_struct *p, int max_to_do);
 static void dispatch_rw_block_io(struct task_struct *p, int index);
-static void dispatch_probe(struct task_struct *p, int index);
 static void dispatch_debug_block_io(struct task_struct *p, int index);
 static void make_response(struct task_struct *p, unsigned long id, 
                           unsigned short op, unsigned long st);
@@ -241,31 +240,35 @@ long do_block_io_op(block_io_op_t *u_block_io_op)
         break;
 
     case BLOCK_IO_OP_VBD_CREATE:  
-       /* create a new VBD for a given domain; caller must be privileged  */
-       if(!IS_PRIV(p))
-           return -EPERM; 
-       ret = vbd_create(&op.u.create_info); 
+       /* create a new VBD */
+       ret = vbd_create(&op.u.create_params); 
        break; 
 
     case BLOCK_IO_OP_VBD_ADD:  
-       /* add an extent to a VBD; caller must be privileged  */
-       if(!IS_PRIV(p))
-           return -EPERM; 
-       ret = vbd_add(&op.u.add_info); 
+       /* add an extent to a VBD */
+       ret = vbd_add(&op.u.add_params); 
        break; 
 
     case BLOCK_IO_OP_VBD_REMOVE:  
-       /* remove an extent from a VBD; caller must be privileged  */
-       if(!IS_PRIV(p))
-           return -EPERM; 
-       ret = vbd_remove(&op.u.remove_info); 
+       /* remove an extent from a VBD */
+       ret = vbd_remove(&op.u.remove_params); 
        break; 
 
     case BLOCK_IO_OP_VBD_DELETE:  
-       /* delete a VBD; caller must be privileged */
-       if(!IS_PRIV(p))
-           return -EPERM; 
-       ret = vbd_delete(&op.u.delete_info); 
+       /* delete a VBD */
+       ret = vbd_delete(&op.u.delete_params); 
+       break; 
+
+    case BLOCK_IO_OP_VBD_PROBE: 
+       /* query VBD information for self or others (or all) */
+       ret = vbd_probe(&op.u.probe_params); 
+       if(ret == 0)
+           copy_to_user(u_block_io_op, &op, sizeof(op)); 
+       break; 
+
+    case BLOCK_IO_OP_VBD_INFO: 
+       /* query information about a particular VBD */
+       ret = vbd_info(&op.u.info_params); 
        break; 
 
     default: 
@@ -403,10 +406,6 @@ static int do_block_io_op_domain(struct task_struct *p, int max_to_do)
            dispatch_rw_block_io(p, i);
            break;
 
-       case XEN_BLOCK_PROBE:
-           dispatch_probe(p, i);
-           break;
-
        case XEN_BLOCK_DEBUG:
            dispatch_debug_block_io(p, i);
            break;
@@ -429,55 +428,6 @@ static void dispatch_debug_block_io(struct task_struct *p, int index)
     DPRINTK("dispatch_debug_block_io: unimplemented\n"); 
 }
 
-
-static void dispatch_probe(struct task_struct *p, int index)
-{
-    extern void ide_probe_devices(xen_disk_info_t *xdi);
-    extern void scsi_probe_devices(xen_disk_info_t *xdi);
-    extern void vbd_probe_devices(xen_disk_info_t *xdi, struct task_struct *p);
-
-    blk_ring_t *blk_ring = p->blk_ring_base;
-    xen_disk_info_t *xdi;
-    unsigned long flags, buffer;
-    int rc = 0;
-    
-    buffer = blk_ring->ring[index].req.buffer_and_sects[0] & ~0x1FF;
-
-    spin_lock_irqsave(&p->page_lock, flags);
-    if ( !__buffer_is_valid(p, buffer, sizeof(xen_disk_info_t), 1) )
-    {
-        DPRINTK("Bad buffer in dispatch_probe_blk\n");
-        spin_unlock_irqrestore(&p->page_lock, flags);
-        rc = 1;
-        goto out;
-    }
-
-    __lock_buffer(buffer, sizeof(xen_disk_info_t), 1);
-    spin_unlock_irqrestore(&p->page_lock, flags);
-
-    /* 
-    ** XXX SMH: all three of the below probe functions /append/ their 
-    ** info to the xdi array; i.e.  they assume that all earlier slots 
-    ** are correctly filled, and that xdi->count points to the first 
-    ** free entry in the array. All kinda gross but it'll do for now.  
-    */
-    xdi = map_domain_mem(buffer);
-    xdi->count = 0; 
-
-    if(IS_PRIV(p)) { 
-       /* privileged domains always get access to the 'real' devices */
-       ide_probe_devices(xdi);
-       scsi_probe_devices(xdi);
-    } 
-    vbd_probe_devices(xdi, p); 
-    unmap_domain_mem(xdi);
-
-    unlock_buffer(p, buffer, sizeof(xen_disk_info_t), 1);
-
- out:
-    make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_PROBE, rc);
-}
-
 static void dispatch_rw_block_io(struct task_struct *p, int index)
 {
     extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); 
index 8ac4f889a7add84c3f16b2e8e280a24e3c9dbc97..a4431a85593bd16a4cd6e7bcb68d36afb3245c09 100644 (file)
 #include <asm/current.h>
 #include <asm/domain_page.h>
 
+/* 
+** XXX SMH: the below probe functions /append/ their info to the 
+** xdi array; i.e.  they assume that all earlier slots are correctly 
+** filled, and that xdi->count points to the first  free entry in 
+** the array. All kinda gross but it'll do for now.  
+*/
+extern int ide_probe_devices(xen_disk_info_t *xdi);
+extern int scsi_probe_devices(xen_disk_info_t *xdi);
+
 
 #if 0
 #define DPRINTK(_f, _a...) printk( _f , ## _a )
 
 /* 
 ** Create a new VBD; all this involves is adding an entry to the domain's
-** vbd hash table. 
+** vbd hash table; caller must be privileged
 */
-long vbd_create(vbd_create_t *create_info
+long vbd_create(vbd_create_t *create_params
 {
     struct task_struct *p; 
     vbd_t *new_vbd, *v; 
     int h; 
 
-    p = find_domain_by_id(create_info->domain);
+    if(!IS_PRIV(current))
+       return -EPERM; 
+
+    p = find_domain_by_id(create_params->domain);
 
     if (!p) { 
        printk("vbd_create attempted for non-existent domain %d\n", 
-              create_info->domain); 
+              create_params->domain); 
        return -EINVAL; 
     }
 
     new_vbd = kmalloc(sizeof(vbd_t), GFP_KERNEL); 
-    new_vbd->vdevice = create_info->vdevice; 
-    new_vbd->mode    = create_info->mode; 
+    new_vbd->vdevice = create_params->vdevice; 
+    new_vbd->mode    = create_params->mode; 
     new_vbd->extents = (xen_extent_le_t *)NULL; 
     new_vbd->next    = (vbd_t *)NULL; 
 
-    h = HSH(create_info->vdevice); 
+    h = HSH(create_params->vdevice); 
     if(p->vbdtab[h]) { 
        for(v = p->vbdtab[h]; v->next; v = v->next) 
            ; 
@@ -65,25 +77,28 @@ long vbd_create(vbd_create_t *create_info)
 ** Add an extent to an existing VBD; fails if the VBD doesn't exist. 
 ** Doesn't worry about overlapping extents (e.g. merging etc) for now. 
 */
-long vbd_add(vbd_add_t *add_info
+long vbd_add(vbd_add_t *add_params
 {
     struct task_struct *p; 
     xen_extent_le_t *x, *xele; 
     vbd_t *v; 
     int h; 
 
-    p = find_domain_by_id(add_info->domain);
+    if(!IS_PRIV(current))
+       return -EPERM; 
+
+    p = find_domain_by_id(add_params->domain);
 
     if (!p) { 
        printk("vbd_add attempted for non-existent domain %d\n", 
-              add_info->domain); 
+              add_params->domain); 
        return -EINVAL; 
     }
 
-    h = HSH(add_info->vdevice); 
+    h = HSH(add_params->vdevice); 
 
     for(v = p->vbdtab[h]; v; v = v->next) 
-       if(v->vdevice == add_info->vdevice)
+       if(v->vdevice == add_params->vdevice)
            break; 
 
     if(!v) {
@@ -92,9 +107,9 @@ long vbd_add(vbd_add_t *add_info)
     }
 
     xele = kmalloc(sizeof(xen_extent_le_t), GFP_KERNEL); 
-    xele->extent.device       = add_info->extent.device; 
-    xele->extent.start_sector = add_info->extent.start_sector; 
-    xele->extent.nr_sectors   = add_info->extent.nr_sectors; 
+    xele->extent.device       = add_params->extent.device; 
+    xele->extent.start_sector = add_params->extent.start_sector; 
+    xele->extent.nr_sectors   = add_params->extent.nr_sectors; 
     xele->next                = (xen_extent_le_t *)NULL; 
 
     if(!v->extents) {
@@ -109,12 +124,157 @@ long vbd_add(vbd_add_t *add_info)
     return 0; 
 }
 
-long vbd_remove(vbd_remove_t *remove_info
+long vbd_remove(vbd_remove_t *remove_params
 {
+    if(!IS_PRIV(current))
+       return -EPERM; 
+
     return -ENOSYS; 
 }
 
-long vbd_delete(vbd_delete_t *delete_info) 
+long vbd_delete(vbd_delete_t *delete_params) 
+{
+    if(!IS_PRIV(current))
+       return -EPERM; 
+
+    return -ENOSYS; 
+}
+
+
+/*
+ * vbd_probe_devices: 
+ *
+ * add the virtual block devices for this domain to a xen_disk_info_t; 
+ * we assume xdi->count points to the first unused place in the array. 
+ */
+static int vbd_probe_devices(xen_disk_info_t *xdi, struct task_struct *p)
+{
+    xen_extent_le_t *x; 
+    xen_disk_t cur_disk; 
+    vbd_t *v; 
+    int i, ret; 
+
+    for(i = 0; i < VBD_HTAB_SZ; i++) { 
+
+       for(v = p->vbdtab[i]; v; v = v->next) { 
+
+           /* SMH: don't ever expect this to happen, hence verbose printk */
+           if ( xdi->count == xdi->max ) { 
+               printk("vbd_probe_devices: out of space for probe.\n"); 
+               return -ENOMEM; 
+           }
+
+           cur_disk.device = v->vdevice; 
+           cur_disk.info   = XD_FLAG_VIRT | XD_TYPE_DISK; 
+           if(!VBD_CAN_WRITE(v))
+               cur_disk.info |= XD_FLAG_RO; 
+           cur_disk.capacity = 0 ; 
+           for(x = v->extents; x; x = x->next) 
+               cur_disk.capacity += x->extent.nr_sectors; 
+           cur_disk.domain   = p->domain; 
+
+           /* Now copy into relevant part of user-space buffer */
+           if((ret = copy_to_user(xdi->disks + xdi->count, &cur_disk, 
+                                  sizeof(xen_disk_t))) < 0) { 
+               printk("vbd_probe_devices: copy_to_user failed [rc=%d]\n", 
+                      ret); 
+               return ret; 
+           } 
+           
+
+           xdi->count++; 
+       }
+    } 
+
+    return 0;  
+}
+
+
+/*
+** Return information about the VBDs available for a given domain, 
+** or for all domains; in the general case the 'domain' argument 
+** will be 0 which means "information about the caller"; otherwise
+** the 'domain' argument will specify either a given domain, or 
+** all domains ("VBD_PROBE_ALL") -- both of these cases require the
+** caller to be privileged. 
+*/
+long vbd_probe(vbd_probe_t *probe_params) 
+{
+    struct task_struct *p = NULL; 
+    int ret;  
+
+    if(probe_params->domain) { 
+
+       /* we can only probe for ourselves unless we're privileged */
+       if(probe_params->domain != current->domain && !IS_PRIV(current))
+           return -EPERM; 
+
+       if(probe_params->domain != VBD_PROBE_ALL) { 
+
+           p = find_domain_by_id(probe_params->domain);
+       
+           if (!p) { 
+               printk("vbd_probe attempted for non-existent domain %d\n", 
+                      probe_params->domain); 
+               return -EINVAL; 
+           }
+
+       }
+
+    } else 
+       /* default is to probe for ourselves */
+       p = current; 
+
+
+    if(!p || IS_PRIV(p)) { 
+
+       /* privileged domains always get access to the 'real' devices */
+       if((ret = ide_probe_devices(&probe_params->xdi))) {
+           printk("vbd_probe: error %d in probing ide devices\n", ret); 
+           return ret; 
+       }
+       if((ret = scsi_probe_devices(&probe_params->xdi))) { 
+           printk("vbd_probe: error %d in probing scsi devices\n", ret); 
+           return ret; 
+       }
+    } 
+    
+
+    if(!p) { 
+
+        u_long flags;
+
+        read_lock_irqsave (&tasklist_lock, flags);
+
+       p = &idle0_task; 
+        while ( (p = p->next_task) != &idle0_task ) {
+            if (!is_idle_task(p)) { 
+               if((ret = vbd_probe_devices(&probe_params->xdi, p))) { 
+                   printk("vbd_probe: error %d in probing virtual devices\n",
+                          ret); 
+                   read_unlock_irqrestore(&tasklist_lock, flags);
+                   return ret; 
+               }
+           }
+       }
+
+       read_unlock_irqrestore(&tasklist_lock, flags);
+               
+    } else { 
+
+       /* probe for disks and VBDs for just 'p' */
+       if((ret = vbd_probe_devices(&probe_params->xdi, p))) { 
+           printk("vbd_probe: error %d in probing virtual devices\n", ret); 
+           return ret; 
+       }
+
+    }
+
+
+    return 0; 
+}
+
+long vbd_info(vbd_info_t *info_params) 
 {
     return -ENOSYS; 
 }
@@ -173,39 +333,6 @@ int vbd_translate(phys_seg_t * pseg, int *nr_segs,
 }
 
 
-/*
- * vbd_probe_devices: 
- *
- * add the virtual block devices for this domain to a xen_disk_info_t; 
- * we assume xdi->count points to the first unused place in the array. 
- */
-void vbd_probe_devices(xen_disk_info_t *xdi, struct task_struct *p)
-{
-    xen_extent_le_t *x; 
-    vbd_t *v; 
-    int i; 
-
-    /* XXX SMH: should allow priv domains to probe vbds for other doms XXX */
-
-    for(i = 0; i < VBD_HTAB_SZ; i++) { 
-       for(v = p->vbdtab[i]; v; v = v->next) { 
-
-           xdi->disks[xdi->count].device   = v->vdevice; 
-           xdi->disks[xdi->count].info     = XD_FLAG_VIRT | XD_TYPE_DISK; 
-
-           if(!VBD_CAN_WRITE(v))
-               xdi->disks[xdi->count].info    |= XD_FLAG_RO; 
-               
-           xdi->disks[xdi->count].capacity = 0; 
-           for(x = v->extents; x; x = x->next) 
-               xdi->disks[xdi->count].capacity += x->extent.nr_sectors; 
-           xdi->count++; 
-       }
-    } 
-
-    return; 
-}
-
 
 
 
index abc94060a1e2a7ad7bb72e7b04cfefdb940396b5..69df07964daa82cb9464fa43b2f49c5d7fdbc950 100644 (file)
@@ -24,14 +24,14 @@ static kdev_t ide_devs[NR_IDE_DEVS] = {
 
 
 
-void ide_probe_devices(xen_disk_info_t* xdi)
+int ide_probe_devices(xen_disk_info_t* xdi)
 {
-    int loop;
+    int loop, ret = 0;
     unsigned int unit;
-    unsigned long capacity; 
-    unsigned short device, type; 
+    unsigned short type; 
     ide_drive_t *drive;
-    
+    xen_disk_t cur_disk; 
+
     for ( loop = 0; loop < MAX_HWIFS; loop++ )
     {
        ide_hwif_t *hwif = &ide_hwifs[loop];
@@ -42,33 +42,42 @@ void ide_probe_devices(xen_disk_info_t* xdi)
             drive = &hwif->drives[unit];
 
             if ( !drive->present ) continue;
+
+
+           /* SMH: don't ever expect this to happen, hence verbose printk */
+           if ( xdi->count == xdi->max ) { 
+               printk("ide_probe_devices: out of space for probe.\n"); 
+               return -ENOMEM;  
+           }
+
             
+           
+           /* SMH: we export 'raw' linux device numbers to domain 0 */
+           cur_disk.device = ide_devs[(loop * MAX_DRIVES) + unit]; 
+
            /* 
            ** NB: we use the ide 'media' field (ide_disk, ide_cdrom, etc) 
            ** as our 'type' field (XD_TYPE_DISK, XD_TYPE_CDROM, etc). 
            ** Hence must ensure these are kept in sync. 
            */
-
-           /* SMH: we export 'raw' linux device numbers to domain 0 */
-            device   = ide_devs[(loop * MAX_DRIVES) + unit]; 
-           type     = drive->media; 
-            capacity = current_capacity(drive);
-
-            xdi->disks[xdi->count].device   = device; 
-            xdi->disks[xdi->count].info     = type; 
-
+           cur_disk.info   = (type = drive->media); 
            if(type == XD_TYPE_CDROM) 
-               xdi->disks[xdi->count].info |= XD_FLAG_RO; 
+               cur_disk.info |= XD_FLAG_RO; 
 
-            xdi->disks[xdi->count].capacity = capacity;
-            xdi->count++;
+           cur_disk.capacity = current_capacity(drive);
+           cur_disk.domain   = 0; /* 'physical' disks belong to domain 0 
 
-            printk("Device %d: IDE-XENO (%s) capacity %ldkB (%ldMB)\n",
-                   xdi->count, (type == XD_TYPE_DISK) ? "disk" : 
-                  ((type == XD_TYPE_CDROM) ? "cdrom" : "unknown"), 
-                  capacity>>1, capacity>>11);
+           /* Now copy into relevant part of user-space buffer */
+           if((ret = copy_to_user(xdi->disks + xdi->count, &cur_disk, 
+                                  sizeof(xen_disk_t))) < 0) { 
+               printk("ide_probe_devices: copy_to_user failed [rc=%d]\n", 
+                      ret); 
+               return ret; 
+           } 
+               
+            xdi->count++;
         }
     }
     
-    return;
+    return ret; 
 }
index 81ef215635613a994be039437e00a56898ddaba8..046e2e55ed64783053ee34518b41818c97030f40 100644 (file)
@@ -1336,32 +1336,39 @@ static kdev_t scsi_devs[NR_SCSI_DEVS] = {
 };
 
 
-void scsi_probe_devices(xen_disk_info_t *xdi)
+int scsi_probe_devices(xen_disk_info_t *xdi)
 {
     Scsi_Disk *sd; 
-    int i;
-    unsigned short device;
-    unsigned long capacity;
+    xen_disk_t cur_disk; 
+    int i, ret;
 
     for ( sd = rscsi_disks, i = 0; i < sd_template.dev_max; i++, sd++ )
     {
         if ( sd->device == NULL ) continue;
 
+       /* SMH: don't ever expect this to happen, hence verbose printk */
+       if ( xdi->count == xdi->max ) { 
+           printk("scsi_probe_devices: out of space for probe.\n"); 
+           return -ENOMEM; 
+       }
+
        /* SMH: we export 'raw' linux device numbers to domain 0 */
-       device   = scsi_devs[i]; 
-        capacity = sd->capacity;
-
-       /* XXX SMH: if make generic, need to properly determine 'type' */
-        xdi->disks[xdi->count].device   = device;
-       xdi->disks[xdi->count].info     = XD_TYPE_DISK; 
-        xdi->disks[xdi->count].capacity = capacity; 
-        xdi->count++; 
-                
-        printk("Device %d: SCSI-XENO (disk) capacity %ldkB (%ldMB)\n",
-               xdi->count, capacity>>1, capacity>>11);
+       cur_disk.device   = scsi_devs[i]; 
+       cur_disk.info     = XD_TYPE_DISK; // XXX SMH: should determine properly
+        cur_disk.capacity = sd->capacity;
+       cur_disk.domain   = 0;            // 'physical' disks belong to dom0 
+
+       /* Now copy into relevant part of user-space buffer */
+       if((ret = copy_to_user(xdi->disks + xdi->count, &cur_disk, 
+                              sizeof(xen_disk_t))) < 0) {  
+           printk("scsi_probe_devices: copy_to_user failed [rc=%d]\n", ret); 
+           return ret; 
+       } 
+       
+       xdi->count++;
     }
 
-    return
+    return 0;
 }      
 
 
index 6d02b4307c5a69ea2bb2c114c03b0da4f21d99f4..e85ad9f9877d737d23b0ffe28897a70191be8dca 100644 (file)
@@ -20,8 +20,7 @@
 #define XEN_BLOCK_WRITE        1
 #define XEN_BLOCK_READA        2
 #define XEN_BLOCK_SPECIAL      4
-#define XEN_BLOCK_PROBE        5   /* get config from hypervisor */
-#define XEN_BLOCK_DEBUG        6   /* debug */
+#define XEN_BLOCK_DEBUG        5   /* debug */
 
 /* NB. Ring size must be small enough for sizeof(blk_ring_t) <= PAGE_SIZE. */
 #define BLK_RING_SIZE        64
@@ -65,7 +64,6 @@ typedef struct blk_ring_st
  * Information about the real and virtual disks we have; used during 
  * guest device probing. 
  */ 
-#define XEN_MAX_DISK_COUNT 64
 
 /* XXX SMH: below types chosen to align with ide_xxx types in ide.h */
 #define XD_TYPE_FLOPPY  0x00
@@ -81,19 +79,23 @@ typedef struct blk_ring_st
 #define XD_FLAG_RO      0x40
 #define XD_FLAG_VIRT    0x80
 #define XD_READONLY(_x) ((_x) & XD_FLAG_RO)
-#define XD_VIRTUAL(_x)  ((_x) & XF_FLAG_VIRT) 
+#define XD_VIRTUAL(_x)  ((_x) & XD_FLAG_VIRT) 
 
 typedef struct xen_disk
 {
     unsigned short device;       /* device number (opaque 16 bit val)  */
     unsigned short info;         /* device type and flags              */
     unsigned long  capacity;     /* size in terms of #512 byte sectors */
+    unsigned int   domain;       /* if a VBD, domain this 'belongs to' */
 } xen_disk_t;
 
 typedef struct xen_disk_info
 {
-  int         count;
-  xen_disk_t  disks[XEN_MAX_DISK_COUNT];
+    /* IN variables  */
+    int         max;             // maximumum number of disks to report
+    xen_disk_t *disks;           // pointer to array of disk info 
+    /* OUT variables */
+    int         count;           // how many disks we have info about 
 } xen_disk_info_t;
 
 #endif
index c9ac0898c75b946833764c3cfeed8dac59c89222..53300bdaba24b1c3fa93a0b284ff21444615a69e 100644 (file)
@@ -13,7 +13,8 @@
 #define BLOCK_IO_OP_VBD_ADD      4    /* add an extent to a given VBD */
 #define BLOCK_IO_OP_VBD_REMOVE   5    /* remove an extent from a given VBD */
 #define BLOCK_IO_OP_VBD_DELETE   6    /* delete a VBD */
-
+#define BLOCK_IO_OP_VBD_PROBE    7    /* query VBD information for a domain */
+#define BLOCK_IO_OP_VBD_INFO     8    /* query info about a particular VBD */
 
 typedef struct _xen_extent { 
     u16       device; 
@@ -32,29 +33,41 @@ typedef struct _xen_extent {
 
   
 typedef struct _vbd_create { 
-    unsigned  domain; 
-    u16       vdevice; 
-    u16       mode; 
+    unsigned     domain;              // create VBD for this domain 
+    u16          vdevice;             // 16 bit id domain will refer to VBD as 
+    u16          mode;                // OR of { VBD_MODE_R , VBD_MODE_W } 
 } vbd_create_t; 
 
 typedef struct _vbd_add { 
-    unsigned     domain; 
-    u16          vdevice; 
-    xen_extent_t extent; 
+    unsigned     domain;              // domain in question 
+    u16          vdevice;             // 16 bit id domain refers to VBD as 
+    xen_extent_t extent;              // the extent to add to this VBD
 } vbd_add_t; 
 
 typedef struct _vbd_remove { 
-    unsigned     domain; 
-    u16          vdevice; 
-    xen_extent_t extent; 
+    unsigned     domain;              // domain in question 
+    u16          vdevice;             // 16 bit id domain refers to VBD as 
+    xen_extent_t extent;              // the extent to remove from this VBD
 } vbd_remove_t; 
 
 
-typedef struct _vbd_delete { 
-    unsigned  domain; 
-    u16       vdevice; 
+typedef struct _vbd_delete {          
+    unsigned     domain;              // domain in question 
+    u16          vdevice;             // 16 bit id domain refers to VBD as 
 } vbd_delete_t; 
 
+#define VBD_PROBE_ALL 0xFFFFFFFF
+typedef struct _vbd_probe { 
+    unsigned         domain;          // domain in question or VBD_PROBE_ALL
+    xen_disk_info_t  xdi;             // where's our space for VBD/disk info
+} vbd_probe_t; 
+
+typedef struct _vbd_info { 
+    unsigned      domain;             // domain in question 
+    u16           vdevice;            // 16 bit id domain refers to VBD as 
+    u16           nextents;           // max no. of extents to return info for
+    xen_extent_t *extents;            // pointer to space for list of extents
+} vbd_info_t; 
 
 
 typedef struct block_io_op_st
@@ -65,10 +78,12 @@ typedef struct block_io_op_st
         /* no entry for BLOCK_IO_OP_SIGNAL */
         /* no entry for BLOCK_IO_OP_RESET  */
        unsigned long ring_mfn; 
-       vbd_create_t  create_info; 
-       vbd_add_t     add_info; 
-       vbd_remove_t  remove_info; 
-       vbd_delete_t  delete_info; 
+       vbd_create_t  create_params; 
+       vbd_add_t     add_params; 
+       vbd_remove_t  remove_params; 
+       vbd_delete_t  delete_params; 
+       vbd_probe_t   probe_params; 
+       vbd_info_t    info_params; 
     }
     u;
 } block_io_op_t;
index 7e9d4c3fa059886b28c44fa7a15d19ebc095f7da..9660756db84c2e47cb20fb8e0253aefbb513cab2 100644 (file)
@@ -30,10 +30,12 @@ typedef struct _vbd {
 
 #define VBD_HTAB_SZ  16       // no. of entries in the vbd hash table. 
 
-long vbd_create(vbd_create_t *create_info); 
-long vbd_add(vbd_add_t *add_info); 
-long vbd_remove(vbd_remove_t *remove_info);
-long vbd_delete(vbd_delete_t *delete_info); 
+long vbd_create(vbd_create_t *create_params); 
+long vbd_add(vbd_add_t *add_params); 
+long vbd_remove(vbd_remove_t *remove_params);
+long vbd_delete(vbd_delete_t *delete_params); 
+long vbd_probe(vbd_probe_t *probe_params); 
+long vbd_info(vbd_info_t *info_params); 
 
 
 /* Describes a [partial] disk extent (part of a block io request) */
index 29619bbbc3ea63a1b54913f12416e647399b6779..31b06c4c98351ee93419a8284fdce454716f0046 100644 (file)
@@ -22,8 +22,14 @@ static unsigned int state = STATE_SUSPENDED;
 static blk_ring_t *blk_ring;
 static unsigned int resp_cons; /* Response consumer for comms ring. */
 static unsigned int req_prod;  /* Private request producer.         */
-static xen_disk_info_t xlblk_disk_info;
+
+#define XDI_MAX 64 
+static xen_disk_info_t xlblk_disk_info; /* information about our disks/VBDs */
+
+#if 0
 static int xlblk_control_msg_pending;
+#endif
+
 
 /* We plug the I/O ring if the driver is suspended or if the ring is full. */
 #define RING_PLUGGED ((BLK_RING_INC(req_prod) == resp_cons) || \
@@ -247,11 +253,13 @@ static int hypervisor_request(unsigned long   id,
 
     switch ( operation )
     {
+#if 0
     case XEN_BLOCK_PROBE:
         if ( RING_PLUGGED ) return 1;
        sector_number = 0;
         DISABLE_SCATTERGATHER();
         break;
+#endif
 
     case XEN_BLOCK_READ:
     case XEN_BLOCK_WRITE:
@@ -430,9 +438,11 @@ static void xlblk_response_int(int irq, void *dev_id, struct pt_regs *ptregs)
             }
            break;
            
+#if 0
         case XEN_BLOCK_PROBE:
             xlblk_control_msg_pending = bret->status;
             break;
+#endif
          
         default:
             BUG();
@@ -447,6 +457,7 @@ static void xlblk_response_int(int irq, void *dev_id, struct pt_regs *ptregs)
 }
 
 
+#if 0
 /* Send a synchronous message to Xen. */
 int xenolinux_control_msg(int operation, char *buffer, int size)
 {
@@ -472,13 +483,14 @@ int xenolinux_control_msg(int operation, char *buffer, int size)
     
     return xlblk_control_msg_pending ? -EINVAL : 0;
 }
+#endif
 
 
 static void reset_xlblk_interface(void)
 {
     block_io_op_t op; 
 
-    xlblk_control_msg_pending = 0;
+//    xlblk_control_msg_pending = 0;
     nr_pending = 0;
 
     op.cmd = BLOCK_IO_OP_RESET;
@@ -500,6 +512,7 @@ static void reset_xlblk_interface(void)
 int __init xlblk_init(void)
 {
     int error; 
+    block_io_op_t op; 
 
     reset_xlblk_interface();
 
@@ -511,11 +524,19 @@ int __init xlblk_init(void)
        goto fail;
     }
 
+    /* Setup our [empty] disk information structure */
+    xlblk_disk_info.max   = XDI_MAX; 
+    xlblk_disk_info.disks = kmalloc(XDI_MAX * sizeof(xen_disk_t), GFP_KERNEL);
+    xlblk_disk_info.count = 0; 
+
     /* Probe for disk information. */
-    memset(&xlblk_disk_info, 0, sizeof(xlblk_disk_info));
-    error = xenolinux_control_msg(XEN_BLOCK_PROBE, 
-                                  (char *)&xlblk_disk_info,
-                                  sizeof(xen_disk_info_t));
+    memset(&op, 0, sizeof(op)); 
+    op.cmd = BLOCK_IO_OP_VBD_PROBE; 
+    op.u.probe_params.domain = 0; 
+    memcpy(&op.u.probe_params.xdi, &xlblk_disk_info, sizeof(xlblk_disk_info)); 
+
+    error = HYPERVISOR_block_io_op(&op); 
+
     if ( error )
     {
         printk(KERN_ALERT "Could not probe disks (%d)\n", error);
@@ -523,6 +544,9 @@ int __init xlblk_init(void)
         goto fail;
     }
 
+    /* copy back the [updated] count parameter */
+    xlblk_disk_info.count = op.u.probe_params.xdi.count; 
+
     /* Pass the information to our virtual block device susbystem. */
     xlvbd_init(&xlblk_disk_info);
 
index ff394a0cdd5070de3fb09b7cf1381637459db95d..08144d967891789006117705cdb0b54d756d94c9 100644 (file)
@@ -65,41 +65,6 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
     }
     break;
 
-    case IOCTL_PRIVCMD_BLKMSG:
-    {
-        privcmd_blkmsg_t blkmsg;
-        char            *kbuf;
-        int              ret;
-  
-        if ( copy_from_user(&blkmsg, (void *)data, sizeof(blkmsg)) )
-            return -EFAULT;
-  
-        if ( blkmsg.buf_size > PAGE_SIZE )
-            return -EINVAL;
-  
-        if ( (kbuf = kmalloc(blkmsg.buf_size, GFP_KERNEL)) == NULL )
-            return -ENOMEM;
-  
-        if ( copy_from_user(kbuf, blkmsg.buf, blkmsg.buf_size) ) {
-            kfree(kbuf);
-            return -EFAULT;
-        }
-  
-        ret = xenolinux_control_msg((int)blkmsg.op, kbuf, blkmsg.buf_size);
-        if ( ret != 0 ) {
-            kfree(kbuf);
-            return ret;
-        }
-  
-        if ( copy_to_user(blkmsg.buf, kbuf, blkmsg.buf_size) ) {
-            kfree(kbuf);
-            return -EFAULT;
-        }
-  
-        kfree(kbuf);
-    }
-    break;
-    
     default:
         ret = -EINVAL;
        break;